Dane pochodzą ze strony https://www.kaggle.com/aadiltajani/fia-f1-19502019-data. Są to 4 pliki:
W celu przenalizowania danych zadałem sobie następujące pytania:
1. Który kierowca wygrał najwięcej wyścigów?
2. Który zespół wygrał najwięcej wyścigów?
3. Kierowcy której narodowości zdobyli najwięcej punktów?
4. Czy kierowcy F1 lepiej radzą sobie na torach domowych?
5. Czy okrążenia torów F1 stają się dłuższe?
6. Jakiej narodowości są kierowcy F1?
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import warnings
from plotly.subplots import make_subplots
warnings.filterwarnings('ignore')
df = pd.read_csv("data/race_wins_1950-2020.csv")
df1 = pd.read_csv("data/drivers_championship_1950-2020.csv")
df3 = pd.read_csv("data/race_results_1950-2020.csv")
fl = pd.read_csv("data/fastest_laps_1950-2020.csv")
df.drop('Unnamed: 0', axis=1, inplace=True)
df1.drop('Unnamed: 0', axis=1, inplace=True)
fl.drop('Unnamed: 0', axis=1, inplace=True)
df3.drop('Unnamed: 0', axis=1, inplace=True)
df["Wins"] = 1
winners = pd.DataFrame(df.groupby(['Name']).Wins.sum().sort_values(ascending=False)).reset_index()
winners = winners[winners.Wins > 10]
fig = px.bar(winners,
x='Name', y='Wins',
color='Wins',
width=750, height=500)
fig.update_layout(title={'text': 'Kierowcy z największą ilością wygranych wyścigów','y':0.95,'x':0.5})
fig.show()
Kierowcą, który wygrał najwięcej wyścigów w historii F1 jest Lewis Hamilton. Drugi jest Michael Schumacher, a podium uzupełnia Sebastian Vettel. Warto zauważyć, że Hamilton jest nadal czynnym kierowcą i obecnie przekroczył już próg 100 wygranych. Pozostali aktywni kierowcy, którzy są w czołówce wszechczasów to: Sebastian Vettel, Fernando Alonso oraz Kimi Raikkonen.
teams = pd.DataFrame(df.groupby(['Team']).Wins.sum().sort_values(ascending=False)).reset_index()
teams = teams[teams.Wins > 10]
fig = px.bar(teams,
x='Team', y='Wins',
color='Wins',
width=750, height=500)
fig.update_layout(title={'text': 'Zespoły z największą ilością wygranych wyścigów','y':0.95,'x':0.5})
fig.show()
Zespół Ferrari zdecydowanie prowadzi w tej klasyfikacji z 239 wygranymi wyścigami. Warto jednak zauważyć, że Scuderia Ferrari startuje w każdym sezonie nieprzerwanie od początku istnienia Formuły 1, czyli od 1950, natomiast Mercedes, zajmujący drugie miejsce z 106 zwycięstwami pierwszy raz wystartował w 2010.
nat = pd.DataFrame(df1.groupby(['Nationality']).Points.sum().sort_values(ascending=False)).reset_index()
nationality = nat[nat.Points > 273]
colors = ['lightslategray',] * 21
colors[20] = 'crimson'
fig = go.Figure(data=[go.Bar(
x=nationality.Nationality, y=nationality.Points,
marker_color=colors)])
fig.update_layout(title_text='Klasyfikacja punktowa według narodowości kierowców')
fig.show()
Wielka Brytania prowadzi w punktowej klasyfikacji wszechczasów, głównie za sprawą Lewisa Hamiltona. Sam Hamilton w tej klasyfikacji zająłby 4 miejsce z wynikiem 3778 punktów. Na wykresie podświetlona została również Polska, reprezentowana przez jednego kierowcę - Roberta Kubicę, któremu udało zebrać się 274 punkty. Jest to najlepszy wynik spośród wszystkich kierowców, którzy jako jedyni reprezentowali swój naród.
Niektórzy kierowcy ze stawki, mają przyjemność rywalizować podczas wyścigów w swojej ojczyźnie. Taki wyścig nazywamy wyścigiem domowym (home race). Postanowiłem sprawdzić, czy kierowcy radzą sobie lepiej w takiej sytuacji, czy jednak presja kibiców działa na nich demotywująco.
df3['Appearances'] = 1
df3.Position = pd.to_numeric(df3.Position, errors='coerce')
drivers = pd.DataFrame(df3.groupby(['Name']).Appearances.sum()).reset_index()
drivers["AveragePosition"] = df3.groupby(['Name']).Position.mean().tolist()
drivers = drivers[drivers.Appearances >= 20].sort_values(by=['AveragePosition'])
driver_nation = df1[['Name', 'Nationality']]
driver_nation.drop_duplicates(inplace=True)
drivers = pd.merge(drivers, driver_nation, on="Name")
drivers.head(10)
| Name | Appearances | AveragePosition | Nationality | |
|---|---|---|---|---|
| 0 | Juan Manuel Fangio | 58 | 2.250000 | ARG |
| 1 | Nino Farina | 36 | 2.814815 | ITA |
| 2 | Alain Prost | 198 | 2.929577 | FRA |
| 3 | Jackie Stewart | 99 | 2.952381 | GBR |
| 4 | Jose Froilan Gonzalez | 29 | 3.000000 | ARG |
| 5 | Ayrton Senna | 155 | 3.238532 | BRA |
| 6 | Lewis Hamilton | 266 | 3.264463 | GBR |
| 7 | Alberto Ascari | 36 | 3.434783 | ITA |
| 8 | Jim Clark | 73 | 3.612245 | GBR |
| 9 | Michael Schumacher | 304 | 3.701245 | GER |
Warto również zwrócić uwagę na otrzymaną tabelkę. Przedstawia ona ranking 10 najlepszych kierowców, biorąc pod uwagę średnią pozycję w wyścigu (wśród kierowców, którzy wzięli udział w conajmniej 20 wyścigach). Juan Manuel Fangio znajduje się na pierwszym miejscu, zajmując średnio 2.25 miejsce. Warto dodać, że jest on 5-krotnym mistrzem świata oraz posiada najwyższy wskaźnik wygranych wyścigów spośród wszystkich kierowców, Fangio wygrał 41% wyścigów (24 z 58) w których brał udział. Należy jednak wziąć pod uwagę fakt, że jeździł on w latach 50., przez co konkurencja i rywalizacja nie była na takim poziomie, na jakim jest obecnie.
df3.Venue[df3.Venue == 'great-britain'] = 'GBR'
df3.Venue[df3.Venue == 'monaco'] = 'MON'
df3.Venue[df3.Venue == 'indianapolis-500'] = 'USA'
df3.Venue[df3.Venue == 'switzerland'] = 'SUI'
df3.Venue[df3.Venue == 'belgium'] = 'BEL'
df3.Venue[df3.Venue == 'france'] = 'FRA'
df3.Venue[df3.Venue == 'italy'] = 'ITA'
df3.Venue[df3.Venue == 'germany'] = 'GER'
df3.Venue[df3.Venue == 'spain'] = 'ESP'
df3.Venue[df3.Venue == 'mexico'] = 'MEX'
df3.Venue[df3.Venue == 'netherlands'] = 'NED'
df3.Venue[df3.Venue == 'argentina'] = 'ARG'
df3.Venue[df3.Venue == 'pescara'] = 'ITA'
df3.Venue[df3.Venue == 'portugal'] = 'POR'
df3.Venue[df3.Venue == 'morocco'] = 'MOR'
df3.Venue[df3.Venue == 'united-states'] = 'USA'
df3.Venue[df3.Venue == 'south-africa'] = 'RSA'
df3.Venue[df3.Venue == 'austria'] = 'AUT'
df3.Venue[df3.Venue == 'canada'] = 'CAN'
df3.Venue[df3.Venue == 'brazil'] = 'BRA'
df3.Venue[df3.Venue == 'sweden'] = 'SWE'
df3.Venue[df3.Venue == 'usa-west'] = 'USA'
df3.Venue[df3.Venue == 'usa-east'] = 'USA'
df3.Venue[df3.Venue == 'japan'] = 'JAP'
df3.Venue[df3.Venue == 'san-marino'] = 'ITA'
df3.Venue[df3.Venue == 'las-vegas'] = 'USA'
df3.Venue[df3.Venue == 'detroit'] = 'USA'
df3.Venue[df3.Venue == 'europe'] = 'GER'
df3.Venue[df3.Venue == 'dallas'] = 'USA'
df3.Venue[df3.Venue == 'australia'] = 'AUS'
df3.Venue[df3.Venue == 'hungary'] = 'HUN'
df3.Venue[df3.Venue == 'pacific'] = 'JAP'
df3.Venue[df3.Venue == 'luxembourg'] = 'LUX'
df3.Venue[df3.Venue == 'malaysia'] = 'MAL'
df3.Venue[df3.Venue == 'bahrain'] = 'BAH'
df3.Venue[df3.Venue == 'china'] = 'CHN'
df3.Venue[df3.Venue == 'turkey'] = 'TUR'
df3.Venue[df3.Venue == 'singapore'] = 'SGP'
df3.Venue[df3.Venue == 'abu-dhabi'] = 'ZEA'
df3.Venue[df3.Venue == 'south-korea'] = 'KOR'
df3.Venue[df3.Venue == 'india'] = 'IND'
df3.Venue[df3.Venue == 'russia'] = 'RUS'
df3.Venue[df3.Venue == 'azerbaijan'] = 'AZE'
df3 = pd.merge(driver_nation, df3, on='Name')
df3['HomeRace'] = df3.Appearances[df3.Venue == df3.Nationality]
home_racers = pd.merge(df3[df3.HomeRace == 1].groupby(['Name']).Position.mean(), drivers, on='Name')
home_racers = home_racers[['Name', 'Nationality', 'Appearances', 'AveragePosition', 'Position']]
home_racers = home_racers.rename(columns={"Position": "AverageHomePos", "AveragePosition": "AveragePos"})
home_racers['HomeDiff'] = home_racers.AveragePos - home_racers.AverageHomePos
home_racers = home_racers.sort_values(by='HomeDiff', ascending=False).dropna()
nat = pd.DataFrame(home_racers.groupby("Nationality").HomeDiff.mean().sort_values(ascending=False)).reset_index()
print("Średnia różnica pozycji: {}".format(home_racers['HomeDiff'].mean()))
Średnia różnica pozycji: -0.1353016645213892
Kierowcy F1 zazwyczaj radzą sobie gorzej podczas wyścigów domowych. Średnio zajmują pozycję niższą o 0.14, porównując do ich średniej pozycji w pozostałej części sezonu. Prawdopodobnie spowodowane jest to dużą presją, którą odczuwają kierowcy. Doping kibiców nie działa na nich tak pozytywnie jak na np. piłkarzy, ponieważ mogą nie słyszeć kibiców oraz w trakcie wyścigu muszą być w pełni skupieni na torze.
fig = px.bar(nat,
x='Nationality', y='HomeDiff',
color='HomeDiff',
width=750, height=500)
fig.update_layout(title={'text': 'Różnica średniej pozycji i pozycji w home race wg narodowości','y':0.95,'x':0.5})
fig.show()
nat.Nationality[nat.Nationality == 'GER'] = 'DEU'
nat.Nationality[nat.Nationality == 'SUI'] = 'CHE'
nat.Nationality[nat.Nationality == 'RSA'] = 'ZAF'
fig = px.choropleth(nat, locations="Nationality",
color="HomeDiff",
hover_name="HomeDiff",
color_continuous_scale=px.colors.sequential.Plasma)
fig.show()
Podczas obserwacji wyników z podziałem na narodowości kierówców zauważyłem bardzo ciekawą zależność. Najlepiej w trakcie domowych wyścigów radzą sobie Australijczycy oraz Kanadyjczycy, na mapie widać również, że korzystniej w porównaniu do Europejczyków wypadają reprezentanci obu Ameryk. Wyścigi w Rosji możemy również zaliczyć do Europy, ponieważ są one najbliżej Starego Kontynentu (Sochi), a Indie możemy pominąć, ponieważ w historii F1 było jedynie dwóch reprezentantów tego kraju, którzy zdobyli łącznie zaledwie 5 punktów. Większość wyścigów odbywa się w Europie, a wiekszość kierowców to Europejczycy.
Kierowcy pochodzący z kontentów innych, niż Europa radzą sobie lepiej podczas wyścigów domowych. Wydaje mi się, że jest to spowodowane zmianą strefy czasowej oraz jet lagiem. Potwierdzić to może fakt, że najlepsi home driverzy pochodzą z Australii oraz Kanady, do których podczas podróży z Europy występują największe zmiany czasu.
Najgorzej podczas domowych wyścigów radzą sobie reprezentanci Monako. Wynika to z tego, że kierowców tego kraju jest bardzo niewiele, a jeden z nich - Charles Leclerc radzi sobie dobrze w trakcie sezonu, jednak podczas domowych wyścigów Monakijczyk posiada swego rodzaju klątwę - jego najlepszy rezultat w Monako to 18 miejsce.
dfs = [home_racers.iloc[:8], home_racers.iloc[-8:]]
top = pd.concat(dfs)
fig = px.bar(top,
x='Name', y='HomeDiff',
color='HomeDiff',
width=750, height=500)
fig.update_layout(title={'text': '8 najlepszych i najgorszych kierowców podczas wyścigów domowych','y':0.95,'x':0.5})
fig.show()
fl = fl.rename(columns={"Lap Time": "LapTime"})
fl.dropna(subset=['Venue', 'LapTime'], inplace=True)
fl.LapTime[fl.LapTime.str[:-7:] == ''] = '0:' + fl.LapTime[fl.LapTime.str[:-7:] == '']
fl['Seconds'] = fl.LapTime.str[-3:].astype(float) / 1000 + fl.LapTime.str[-6:-4].astype(float) + fl.LapTime.str[:-7:].astype(float) * 60
flaps = pd.DataFrame(fl.groupby(['Venue','Year']).Seconds.mean()).reset_index()
fig = px.scatter(flaps[flaps.Year > 1980],
x="Year", y="Seconds",
trendline="ols",
trendline_color_override="red")
fig.update_layout(title={'text': 'Najszybsze okrążenia wyścigu w latach 2000-2020','y':0.95,'x':0.5})
fig.show()
italy = flaps[flaps.Venue == "Italy"]
britain = flaps[flaps.Venue == "Great Britain"]
monaco = flaps[flaps.Venue == "Monaco"]
france = flaps[flaps.Venue == "France"]
fig = px.scatter(italy[italy.Year >= 1980],
x="Year", y="Seconds",
trendline="ols",
trendline_color_override="red")
fig.update_layout(title={'text': 'Najszybsze okrążenia GP Włoch w latach 1980-2020','y':0.95,'x':0.5})
fig.show()
fig = px.scatter(britain[britain.Year >= 1980],
x="Year", y="Seconds",
trendline="ols",
trendline_color_override="red")
fig.update_layout(title={'text': 'Najszybsze okrążenia GP Wielkiej Brytanii w latach 1980-2020','y':0.95,'x':0.5})
fig.show()
fig = make_subplots(
rows=2, cols=2,
subplot_titles=("GP Włoch", "GP Wielkiej Brytanii", "GP Monako", "GP Francji"))
fig.add_trace(go.Scatter(x=italy.Year, y=italy.Seconds,
mode="markers", name='Włochy'),
row=1, col=1)
fig.add_trace(go.Scatter(x=britain.Year, y=britain.Seconds,
mode="markers", name='Wielka Brytania'),
row=1, col=2)
fig.add_trace(go.Scatter(x=monaco.Year, y=monaco.Seconds,
mode="markers", name='Monako'),
row=2, col=1)
fig.add_trace(go.Scatter(x=france.Year, y=france.Seconds,
mode="markers", name='Francja'),
row=2, col=2)
fig.update_layout(title={'text': 'Czas najszybszego okrążenia na wybranych GP w latach 1950-2020','y':0.95,'x':0.5})
fig.show()
Ciężko stwierdzić, czy średni czas najszybszego okrążenia wyścigu zmienia się z upływem czasu. Biorąc pod uwagę wszystkie wyścigi z lat 1980-2020, średni czas utrzymuje się stale na poziomie 85.5s. Na średni najlepszy czas sezonu wpływa wiele zmiennych: tory, na których odbędą się wyścigi, warunki pogodowe, wybrane nitki toru. Warunki pogodowe diametralnie wpływają na czas okrążenia, oprócz tego każdy tor ma wiele możliwych kombinacji zakrętów i prostych, które często się zmieniają, są przebudowywane, przez co każdego roku, ten sam tor może mieć mocno różniące się czasy. Dla przykładu kierowcy na torze Monza, na którym odbywa się GP Włoch z roku na rok osiągają lepsze czasy, natomiast sytuacja wygląda odwrotnie na torze Silverstone, gdzie kierowcy rywalizują w GP Wielkiej Brytanii. Duże znaczenia ma to, w jaki sposób tor jest przebudowywany.
Warto również zwrócić uwagę na to, że patrząc na różne tory w latach 1950-2020, widzimy, że aktualnie bolidy oraz kierowcy są w lepszym stopniu przygotowani na niekorzystne warunki atmosferyczne. Ciężko znaleźć na wykresie w ostatnich latach tak duże rozbieżności jak w latach 1950-1970.
nations = df1[['Name', 'Nationality']].copy().drop_duplicates().reset_index().drop('index', 1)
nations['Drivers'] = 1
nations = nations.groupby('Nationality').sum().reset_index().sort_values(by="Drivers", ascending=False)
nations.Nationality[nations.Nationality == 'GER'] = 'DEU'
nations.Nationality[nations.Nationality == 'SUI'] = 'CHE'
nations.Nationality[nations.Nationality == 'RSA'] = 'ZAF'
nations.Nationality[nations.Nationality == 'POR'] = 'PRT'
nations.Nationality[nations.Nationality == 'DEN'] = 'DNK'
nations.Nationality[nations.Nationality == 'NED'] = 'NLD'
fig = px.choropleth(nations, locations="Nationality",
color="Drivers",
hover_name="Drivers",
color_continuous_scale=px.colors.sequential.Plasma)
fig.update_layout(title={'text': 'Narodowość kierowców F1 w 1950-2020','y':0.95,'x':0.5})
fig.show()
Podczas przygotowania odpowiedzi na to pytanie, zauważyłem, że nasze dane nie są do końca kompletne, niektórzy kierowcy, których przygoda z Formułą 1 była epizodyczna zostali pominięci. Dla przykładu, wg Wikipedii najwięcej kierowców pochodziło z USA (230), ale aż 176 z nich występowało jedynie w jednym wyścigu w sezonie (Indianapolis 500).
Jak widać na mapie, większość kierowców pochodzi z Europy. Najliczniej reprezentowane są: Wielka Brytania, USA, Włochy, Francja, Niemcy oraz Brazylia. Kierowca, aby rozpocząć ściganie w Formule 1 potrzebuje dużego zaplecza finansowego lub wsparcia sponsorów, dlatego ten sport jest zdominowany przez bogate, rozwinięte kraje.